#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <pthread.h>

#define SERVER_IP "113.45.219.22"
#define SERVER_PORT 8888
#define BUFFER_SIZE 1024

// 全局变量，用于存储Socket描述符
int sockfd;

// 后台接收数据的线程函数
void* receive_data(void* arg) {
    char buffer[BUFFER_SIZE];
    int bytes_read;

    while (1) {
        bytes_read = recv(sockfd, buffer, BUFFER_SIZE - 1, 0);
        if (bytes_read > 0) {
            buffer[bytes_read] = '\0';
            printf("Received: %s\n", buffer);
        } else if (bytes_read == 0) {
            printf("Server disconnected.\n");
            pthread_exit(NULL); // 退出线程
        } else {
            perror("recv");
            break;
        }
    }

    close(sockfd);
    pthread_exit(NULL);
}

// 前台发送数据的函数（在主线程中运行）
void send_data() {
    char buffer[BUFFER_SIZE];

    while (1) {
        printf("Enter message to send: ");
        fgets(buffer, BUFFER_SIZE, stdin);
        // 去掉换行符
        buffer[strcspn(buffer, "\n")] = 0;

        int bytes_sent = send(sockfd, buffer, strlen(buffer), 0);
        if (bytes_sent < 0) {
            perror("send");
            break;
        }
    }

    close(sockfd);
}

int main() {
    pthread_t recv_thread;
    struct sockaddr_in server_addr;

    // 创建Socket
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        perror("socket");
        exit(EXIT_FAILURE);
    }

    // 初始化服务器地址结构
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(SERVER_PORT);
    if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) {
        perror("inet_pton");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    // 连接到服务器
    if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
        perror("connect");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    // 创建后台接收数据的线程
    if (pthread_create(&recv_thread, NULL, receive_data, NULL) != 0) {
        perror("pthread_create");
        close(sockfd);
        exit(EXIT_FAILURE);
    }

    // 在前台发送数据
    send_data();

    // 注意：在实际应用中，通常不会在这里关闭sockfd，因为recv_thread还在使用它。
    // 但在这个简单示例中，由于send_data函数在遇到错误时会关闭sockfd，并且recv_thread在检测到服务器断开连接时也会退出，
    // 所以这里不需要额外的同步机制来确保sockfd在recv_thread退出后才被关闭。
    // 在更复杂的应用中，应该使用适当的同步机制（如互斥锁和条件变量）来管理sockfd的关闭。

    // 等待后台线程结束（可选，但在这个示例中不是必需的，因为recv_thread会在服务器断开连接时自行退出）
    // pthread_join(recv_thread, NULL);

    // 在这个简单示例中，我们不需要等待recv_thread，因为当send_data函数关闭sockfd时，recv_thread会检测到EOF并退出。
    // 但是，在更复杂的应用中，你可能需要确保所有线程都正确清理并退出。

    return 0;
}